123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- "use client";
- import { loginApi, registerApi, userInfoApi } from "@/api/login";
- import Box from "@/components/Box";
- import ButtonOwn from "@/components/ButtonOwn";
- import MobileField from "@/components/Fields/MobileField";
- import { useEventPoint } from "@/hooks/useEventPoint";
- import { Link, useRouter } from "@/i18n/routing";
- import { useSystemStore } from "@/stores/useSystemStore";
- import { useUserInfoStore } from "@/stores/useUserInfoStore";
- import { emailReg, neReg } from "@/utils";
- import { setCookies } from "@/utils/Cookies";
- import { Local } from "@/utils/storage";
- import {
- Checkbox,
- DatePicker,
- DatePickerRef,
- Form,
- Input,
- Radio,
- Space,
- TextArea,
- Toast,
- } from "antd-mobile";
- import { PickerDate } from "antd-mobile/es/components/date-picker/util";
- import clsx from "clsx";
- import dayjs from "dayjs";
- import { useTranslations } from "next-intl";
- import { useSearchParams } from "next/navigation";
- import { FC, RefObject, useEffect, useRef, useState } from "react";
- import styles from "./style.module.scss";
- interface MobileFieldProps {
- value?: string;
- onChange?: (value: string) => void;
- }
- // const MobileField: FC<MobileFieldProps> = (props) => {
- // const t = useTranslations("form");
- // const { value, onChange } = props;
- //
- // const changeHandler = (value: string) => {
- // let newAmount = value.replace(/[^0-9]/g, "");
- // if (onChange) {
- // onChange(newAmount);
- // }
- // };
- // return (
- // <>
- // <Space align="center" className={"text-[#ccc]"}>
- // <Space align="center">+55</Space>
- // <Input
- // placeholder={t("phone")}
- // maxLength={11}
- // value={value}
- // onChange={(e) => changeHandler(e)}
- // />
- // </Space>
- // </>
- // );
- // };
- const SexMobile: FC<MobileFieldProps> = (props) => {
- const { value, onChange } = props;
- const handler = () => {
- console.log(`🚀🚀🚀🚀🚀-> in index.tsx on 58`, 123);
- };
- return (
- <div className={"w-[100%] border-4"} onClick={handler}>
- <Space align="center" className={"border-4 text-[#ccc]"}>
- <div className={"h-full w-[100%]"}>{value}</div>
- </Space>
- </div>
- );
- };
- interface FormProps {
- /**
- * 通讯地址
- */
- address?: string;
- /**
- * 用户头像
- */
- avatar_url?: string;
- /**
- * 生日:yyyy-MM-dd
- */
- birthday?: string;
- /**
- * 邮箱地址
- */
- email?: string;
- /**
- * 真实姓名
- */
- nick_name?: string;
- /**
- * 外部ID
- */
- open_id?: string;
- /**
- * 身份护照
- */
- passport?: string;
- /**
- * 用户密码
- */
- pwd: string;
- /**
- * 推荐码
- */
- referrer_code?: string;
- /**
- * 用户名
- */
- user_name?: string;
- /**
- * 用户电话号码
- */
- user_phone: string;
- /**
- * 用户类型
- */
- user_type?: string;
- sex?: number;
- /**
- * 渠道链接
- */
- channel_code?: string;
- code_phone?: string;
- first_name?: string;
- last_name?: string;
- }
- interface FormInitStateTypes extends FormProps {
- mobile?: {
- preValue: string;
- realValue: string;
- };
- }
- export type FormType = "login" | "register";
- interface Props {
- type?: FormType;
- }
- const FormComponent: FC<Props> = (props) => {
- const { type = "register" } = props;
- const isStrictMode = useSystemStore().identity_verify.register === 1;
- const { setUserInfo } = useUserInfoStore();
- const t = useTranslations();
- const searchParams = useSearchParams();
- const [statusText, setStatusText] = useState("");
- const { eventLogin, eventRegister } = useEventPoint();
- const formRef = useRef<any>(null);
- /// 密码可见
- const [visible, setVisible] = useState(false);
- const spanClassName = clsx("iconfont", {
- "icon-kejian": visible,
- "icon-bukejian": !visible,
- });
- // 是否同意协议
- const [checkBoxValue, setCheckBoxValue] = useState<boolean>(false);
- const router = useRouter();
- /// 初始值
- const params = useRef<FormInitStateTypes>({
- user_phone: "",
- mobile: { preValue: "55", realValue: "" },
- pwd: "",
- sex: 0,
- address: undefined,
- birthday: undefined,
- email: undefined,
- passport: undefined,
- referrer_code: undefined,
- });
- useEffect(() => {
- formRef.current?.resetFields();
- }, [type]);
- const onFinish = (values: FormInitStateTypes) => {
- const { mobile } = values;
- const newValue = {
- ...values,
- user_phone: `${mobile?.preValue}${mobile?.realValue}`,
- code_phone: mobile?.preValue,
- };
- delete newValue.mobile;
- if (isStrictMode) {
- strictHandler(newValue as FormProps);
- } else {
- looseHandler(newValue as FormProps);
- }
- };
- /// 严格模式
- const strictHandler = (values: FormProps) => {
- if (type !== "login") {
- if (!checkBoxValue) {
- Toast.show({
- content: t("form.readyAgreement"),
- });
- return;
- }
- values.birthday = dayjs(values.birthday).format("YYYY/MM/DD");
- }
- looseHandler(values);
- };
- const loginHandler = async (values: FormProps) => {
- return new Promise(async (resolve, reject) => {
- const loginResult = await loginApi(values).catch((error) => {
- let text = error ? t(`code.${error.data.code}`) : t(`code.${500}`);
- Toast.show({
- content: text,
- });
- });
- if (loginResult?.code === 200) {
- eventLogin();
- setCookies("Token", loginResult.data.token as string);
- // loginAction(loginResult.data.token)
- const result = await userInfoApi();
- if (result.code === 200) {
- setUserInfo(result.data);
- resolve(result);
- return result;
- }
- } else {
- reject();
- }
- });
- };
- /// 宽松模式
- const looseHandler = async (values: FormProps) => {
- // 请求
- Toast.show({
- icon: "loading",
- duration: 0,
- });
- // 注册
- if (type === "register") {
- values.user_name = `${values.first_name} ${values.last_name}`;
- delete values.first_name;
- delete values.last_name;
- const newValues = {
- ...values,
- referrer_code: sessionStorage.getItem("shareId") ?? undefined,
- channel_code: Local.getKey("channel_code") ?? undefined,
- // 轮盘邀请
- turntable_id: Number(sessionStorage.getItem("turntable_id")) ?? undefined,
- turntable_user_id: Number(sessionStorage.getItem("turntable_user_id")) ?? undefined,
- turntable_time: Number(sessionStorage.getItem("turntable_time")) ?? undefined,
- // 快玩id
- click_id: Local.getKey("ban_click_id") ?? undefined,
- };
- registerApi(newValues)
- .then(async (res) => {
- if (res.code === 200) {
- eventRegister();
- loginHandler({
- pwd: values.pwd,
- user_phone: values.user_phone,
- code_phone: values.code_phone,
- }).then(() => {
- router.replace("/recharge");
- Toast.clear();
- });
- }
- })
- .catch((error) => {
- console.log(`🚀🚀🚀🚀🚀-> in index.tsx on 257`, error);
- if (error.data?.code === 1017) {
- sessionStorage.removeItem("shareId");
- }
- Toast.show({
- content: t(`code.${error.data?.code ?? 500}`),
- });
- });
- } else {
- /// 登录
- loginHandler(values).then(() => {
- Toast.clear();
- const redirect = searchParams.get("redirect")
- ? `/${searchParams.get("redirect")}`
- : "/";
- router.replace(redirect);
- });
- }
- };
- const onConfirm = (value: PickerDate) => {
- const isChildren = dayjs().subtract(18, "year").isBefore(value);
- if (isChildren) {
- Toast.show({
- icon: "fail",
- content: t("form.NotSuitableForChildren"),
- });
- }
- };
- const ageValidator = (rule: any, value: PickerDate) => {
- const isChildren = dayjs().subtract(18, "year").isBefore(value);
- if (isChildren) {
- return Promise.reject(new Error(rule.message));
- } else {
- return Promise.resolve();
- }
- };
- // 手机号验证规则
- const checkMobile = (_: any, value: any) => {
- const reg = /^.{2}9/;
- if (!reg.test(value.realValue)) {
- return Promise.reject(new Error(t("form.phoneRules")));
- } else if (value.realValue.length < 10) {
- return Promise.reject(new Error(t("form.phoneMinReg")));
- } else {
- return Promise.resolve();
- }
- };
- return (
- <Box className={clsx(styles.loginForm, "custom-form")}>
- <Form
- style={{
- "--border-bottom": "none",
- "--border-top": "none",
- "--border-inner": "none",
- }}
- ref={formRef}
- initialValues={params.current}
- onFinish={onFinish}
- footer={
- <ButtonOwn active className={clsx(styles.btn, "font-bold")}>
- {type === "login" ? t("form.loginText") : t("form.registerText")}
- </ButtonOwn>
- }
- >
- <Form.Item name="mobile" rules={[{ required: true, validator: checkMobile }]}>
- <MobileField />
- </Form.Item>
- <Form.Item
- name="pwd"
- label={
- <i className="iconfont icon-xiugaimima text-[.18rem] text-[#465461]"></i>
- }
- extra={
- <span className={spanClassName} onClick={() => setVisible(!visible)}></span>
- }
- layout="horizontal"
- rules={[
- { required: true, message: t("form.passwordReg") },
- { min: 6, max: 20, message: t("form.passwordMinReg") },
- ]}
- >
- <Input
- placeholder={t("form.password")}
- maxLength={20}
- type={visible ? "text" : "password"}
- />
- </Form.Item>
- {type !== "login" && isStrictMode ? (
- <>
- {/* <Form.Item
- name="user_name"
- label=""
- rules={[{ required: true, message: t("form.usernameReg") }]}
- >
- <Input placeholder={t("form.username")} />
- </Form.Item> */}
- <div className="flex items-center">
- <Form.Item
- name="first_name"
- className="mr-[.1rem] w-[1.4rem]"
- layout="horizontal"
- label={
- <i className="iconfont icon-yonghu1 text-[.18rem] leading-[1] text-[#465461]"></i>
- }
- rules={[{ required: true, message: t("form.usernameReg") }]}
- >
- <Input placeholder={"Insira seu nome"} />
- </Form.Item>
- <Form.Item
- className="flex-1"
- name="last_name"
- label=""
- rules={[{ required: true, message: t("form.usernameReg") }]}
- >
- <Input placeholder={"Insira seu sobrenome"} />
- </Form.Item>
- </div>
- <Form.Item
- name="birthday"
- clickable={false}
- trigger={"onConfirm"}
- arrowIcon={<i className={"iconfont icon-xiangyou1"}></i>}
- onClick={(e, datePickerRef: RefObject<DatePickerRef>) => {
- datePickerRef.current?.open();
- }}
- rules={[
- { required: true, message: t("form.birthdayReg") },
- {
- message: t("form.NotSuitableForChildren"),
- validator: ageValidator,
- },
- ]}
- >
- <DatePicker
- getContainer={null}
- min={dayjs().subtract(50, "year").toDate()}
- max={dayjs().toDate()}
- style={{ background: "#fff", color: "#000" }}
- >
- {(value) =>
- value ? (
- dayjs(value).format("YYYY/MM/DD")
- ) : (
- <span className={"text-[#ccc]"}>{t("form.birthday")}</span>
- )
- }
- </DatePicker>
- </Form.Item>
- <Form.Item
- name="email"
- layout="horizontal"
- label={
- <i className="iconfont icon-youjian text-[.13rem] leading-[1] text-[#465461]"></i>
- }
- rules={[
- { required: true, message: t("form.emailReg"), pattern: emailReg },
- ]}
- >
- <Input placeholder={t("form.email")} />
- </Form.Item>
- <Form.Item name="sex">
- <Radio.Group>
- <Radio
- value={0}
- className={"mr-[0.1rem]"}
- style={{ "--icon-size": "18px" }}
- >
- {t("form.sexMan")}
- </Radio>
- <Radio value={1} style={{ "--icon-size": "18px" }}>
- {t("form.sexWoman")}
- </Radio>
- </Radio.Group>
- </Form.Item>
- <Form.Item
- name="passport"
- layout="horizontal"
- label={
- <i className="iconfont icon-shenfengzheng text-[.18rem] leading-[1] text-[#465461]"></i>
- }
- rules={[{ required: true, message: t("form.cardReg"), pattern: neReg }]}
- >
- <Input placeholder={t("form.card")} maxLength={11} type={"text"} />
- </Form.Item>
- <Form.Item
- name="address"
- label=""
- rules={[{ required: true, message: t("form.addressReg") }]}
- >
- <TextArea placeholder={t("form.address")} maxLength={40} />
- </Form.Item>
- <div className={"flex px-[0.1rem]"}>
- <Checkbox
- block
- style={{ "--icon-size": "16px" }}
- checked={checkBoxValue}
- onChange={(value) => setCheckBoxValue(value)}
- ></Checkbox>
- <div className={"ml-[10px] select-none break-all text-[12px]"}>
- {t("form.agreement")}
- <Link href={"/preventLaunderMoney"} className={"text-[#1677ff]"}>
- {t("form.moneyAgreement")}
- </Link>
- 、
- <Link href={"/terms"} className={"text-[#1677ff]"}>
- {t("form.serverAgreement")}
- </Link>
- {t("form.agreementAnd")}
- <Link href={"/gamingPolicy"} className={"text-[#1677ff]"}>
- {t("form.childrenAgreement")}
- </Link>
- </div>
- </div>
- </>
- ) : null}
- <div className="mb-[0.2rem] flex justify-end text-[0.12rem]">
- {type == "login" && (
- <>
- <Link className={"text-[#677787]"} href="/resetPhone">
- {t("LoginPage.forgetPwd")}
- </Link>
- {/* <Link className={"text-[#fff]"} href="/register">
- {t("LoginPage.registerGo")}
- </Link> */}
- </>
- )}
- </div>
- </Form>
- </Box>
- );
- };
- export default FormComponent;
|